package cn.zh.base.service.impl;

import cn.zh.base.constant.PhoneRegisterCons;
import cn.zh.base.constant.WechatCons;
import cn.zh.base.dto.LoginDto;
import cn.zh.base.dto.WeChatDto;
import cn.zh.base.dto.WechatBinderDto;
import cn.zh.base.service.LoginService;
import cn.zh.base.util.*;
import cn.zh.user.domain.Logininfo;
import cn.zh.user.domain.User;
import cn.zh.user.domain.Wxuser;
import cn.zh.user.mapper.LogininfoMapper;
import cn.zh.user.mapper.UserMapper;
import cn.zh.user.mapper.WxuserMapper;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {
    @Autowired
    private LogininfoMapper mapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WxuserMapper wxuserMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public AjaxResult login(LoginDto dto) {
        Logininfo logininfo = (Logininfo) mapper.findByAccount(dto);
        if (logininfo == null) {
            throw new BusinessException("账号或密码错误");
        }
        String passParm = dto.getPassword();
        String salt = logininfo.getSalt();
        String pwd = MD5Utils.encrypByMd5(salt + passParm);
        String password = logininfo.getPassword();
        log.info(pwd);
        log.info(password);
        log.info(salt);
        if (StringUtils.isBlank(pwd) || StringUtils.isBlank(password) || !pwd.equals(password)) {
            throw new BusinessException("账号或者密码错误！");
        }
        Map<String, Object> map = getMap(logininfo);
        return AjaxResult.me().success(map);
    }

    @Override
    public AjaxResult wechat(WeChatDto dto) {
        // 1.参数校验
        // 2.请求微信的第二个接口 获取token和openiD
        String url = String.format(WechatCons.SECOND, WechatCons.APPID, WechatCons.SECRET, dto.getCode());
        String jsonStr = HttpClientUtils.httpGet(url);
        if (StringUtils.isBlank(jsonStr)) {
            throw new BusinessException("未接收到微信传入的信息!");
        }
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        // 从里面取值 是get
        String accessToken = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");
        if (StringUtils.isBlank(accessToken) || StringUtils.isBlank(openid)) {
            throw new BusinessException("未接收到微信传入的信息!!");
        }
        // 3.根据openId 查询wxuser表 是否有数据
        Wxuser wxuser = wxuserMapper.findByOpenid(openid);
        if (wxuser != null) {
            Logininfo logininfo = mapper.findByUserId(wxuser.getUserId());
            Map<String, Object> map = getMap(logininfo);
            return AjaxResult.me().success(map);
        }
        StringBuffer stringBuffer = new StringBuffer()
                .append("?accessToken=")
                .append(accessToken)
                .append("&openId=")
                .append(openid);
        return AjaxResult.me().fail("nobinder").setResultObj(stringBuffer);
    }

    @Override
    public AjaxResult wechatBinder(WechatBinderDto dto) {
        // 1.参数校验
        // 判断手机号验证码是否正确
        String phoneCode = (String) redisTemplate.opsForValue().get(String.format(PhoneRegisterCons.BINDER_CODE_KEY, dto.getPhone()));
        if (StringUtils.isBlank(phoneCode) || !dto.getVerifyCode().equals(phoneCode)) {
            throw new BusinessException("验证码错误！");
        }
        // 2.根据token和openId调用第三个接口
        String url = String.format(WechatCons.THIRD, dto.getAccessToken(), dto.getOpenId());
        String jsonStr = HttpUtil.httpGet(url);
        System.out.println(jsonStr);
        if (StringUtils.isBlank(jsonStr)) {
            throw new BusinessException("未获取微信传来的数据！");
        }
        // jsonObject 会将json字符串直接转成对象 前提：字段要一样
        Wxuser wxuser = JSONObject.parseObject(jsonStr, Wxuser.class);
        if (wxuser == null) {
            throw new BusinessException("未获取微信传来的数据!!");
        }
        // 根据手机号查询user里面是否有数据
        User user = userMapper.findByPhone(dto.getPhone());
        Logininfo logininfo = new Logininfo();
        if (user == null) {
            user = dto.getUser();
            BeanUtils.copyProperties(user,logininfo);
            logininfo.setDisable(true);
            logininfo.setType(1);
            mapper.add(logininfo);
            user.setLogininfoId(logininfo.getId());
            userMapper.add(user);
        } else {
            logininfo = mapper.findByUserId(user.getId());
        }
        // 有 直接绑定wxuser
        wxuser.setUserId(user.getId());
        wxuserMapper.add(wxuser);
        // 返回登陆成功
        Map<String, Object> map = getMap(logininfo);
        // 发送短信
//        SmsUtil.send(dto.getPhone(), "尊敬的用户您好，欢迎注册牲畜商城，您的初始密码为：123456,请尽快修改密码");
        return AjaxResult.me().success(map);
    }

    private Map<String, Object> getMap(Logininfo logininfo) {
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, logininfo,30, TimeUnit.MINUTES);
        logininfo.setPassword(null);
        logininfo.setPhone(null);
        logininfo.setSalt(null);
        logininfo.setEmail(null);
        Map<String, Object> map = new HashMap<>();
        map.put("token",token);
        map.put("logininfo", logininfo);
        return map;
    }
}
